/**
 * create by young (young2f@outlook.com) on 2024/4/21
 */
'use strict';
const base = require('../base/controllerBase');
const _stringUtils = require('../utils/stringUtils');
const _service = 'financeService';
const moment = require('moment');
const _ = require('lodash');

class FinanceController extends base {
  async findBankAccountMany() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
      };

      ctx.validate(model, body);
      const { tenantCode } = body;
      const result = await ctx.app.dbs.find('BankAccount', { tenantCode });

      ctx.body = { status: 'ok', result };
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async createBankAccount() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },

      };

      ctx.validate(model, body);
      body.code = _stringUtils.getCode('BAC');
      const result = await ctx.app.dbs.insert('BankAccount', body);

      ctx.body = { status: 'ok', result };
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async deleteBankAccount() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
        code: { type: 'string' },
      };

      ctx.validate(model, body);
      const { code, tenantCode } = body;
      const paymentRes = await ctx.app.dbs.find('Payment', { accountCode:code, tenantCode });
      if(paymentRes.length){
        throw new Error(`账户已有付款记录，不可删除！`);
      }
      const receiptRes = await ctx.app.dbs.find('Receipt', { accountCode:code, tenantCode });
      if(receiptRes.length){
        throw new Error(`账户已有收款记录，不可删除！`);
      }
      const result = await ctx.app.dbs.deleteOne('BankAccount', { code, tenantCode });

      ctx.body = { status: 'ok', result };
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async updateBankAccount() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
        code: { type: 'string' },
      };

      ctx.validate(model, body);
      const { code, tenantCode } = body;
      const result = await ctx.app.dbs.updateOne('BankAccount', { code, tenantCode }, body);

      ctx.body = { status: 'ok', result };
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  /**
   * 获取上月结余
   * @returns {Promise<void>}
   */
  async getLastMonthBalance() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
        accountCode: { type: 'string' },
      };

      ctx.validate(model, body);
      const { tenantCode, accountCode } = body;
      const query = { tenantCode, code: accountCode };
      const bankAccount = await ctx.app.dbs.findOne('BankAccount', query);
      console.log('bankAccount', bankAccount);
      const initBalance = bankAccount && bankAccount.initBalance ? bankAccount.initBalance : 0;
      const end = moment()
        .subtract(1, 'months')
        .endOf('month');
      const start = moment()
        .subtract(1, 'months')
        .startOf('month');
      console.log(start);
      console.log(end);
      delete query.code;
      query.date = { '$gt': start, '$lt': end };
      query.accountCode = accountCode;
      const list = await ctx.app.dbs.find('Receipt', query);

      let _receipt = 0,
        _payment = 0;
      _.map(list, item => {
        const { receipt, payment } = item;
        _.map(receipt, it => {
          const { amount } = it;
          _receipt += amount;
        });
        _.map(payment, it => {
          const { amount } = it;
          console.log('payment', amount);
          _payment += amount;
        });
      });
      console.log('receipt', _receipt, '_payment', _payment, 'initBalance', initBalance);
      const balance = _receipt - _payment + initBalance;
      ctx.body = { status: 'ok', result: { balance } };
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  /**获取账号下的结余
   *
   * @returns {Promise<void>}
   */
  async getBalance() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
        accountCode: { type: 'string' },
      };

      ctx.validate(model, body);
      const { tenantCode, accountCode } = body;
      const query = { tenantCode, code: accountCode };
      const bankAccount = await ctx.app.dbs.findOne('BankAccount', query);
      const list = await ctx.app.dbs.find('Receipt', { tenantCode, accountCode });
      console.log('find balance', query, list);
      let _receipt = 0,
        _payment = 0;
      _.map(list, item => {
        const { receipt, payment } = item;
        _.map(receipt, it => {
          const { amount } = it;
          _receipt += amount;
        });
        _.map(payment, it => {
          const { amount } = it;
          console.log('payment', amount);
          _payment += amount;
        });
      });
      const initBalance = bankAccount && bankAccount.initBalance ? bankAccount.initBalance : 0;

      const balance = _receipt - _payment + initBalance;
      ctx.body = { status: 'ok', result: { balance } };
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async createRecord() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
        code: { type: 'string' },
      };
      console.log('create record', body);
      ctx.validate(model, body);
      const result = await service[_service].createRecord(body);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async updateRecord() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
        code: { type: 'string' }
      };

      ctx.validate(model, body);
      const result = await service[_service].updateRecord(body);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async deleteRecord() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
        code: { type: 'string' }
      };

      ctx.validate(model, body);
      const result = await service[_service].deleteRecord(body);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async findRecord() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
        table: { type: 'string' },
        code: { type: 'string' },
      };

      ctx.validate(model, body);

      const result = await service[_service].findRecord(body);

      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async findRecordMany() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
      };

      ctx.validate(model, body);

      const result = await service[_service].findRecordMany(body);

      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }
  async findProcureRecordMany() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
      };
      console.log('findProcureRecordMany body', body);
      ctx.validate(model, body);

      const result = await service[_service].findProcureRecordMany(body);
      console.log('find payment many', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }
  async findRecordStatistics() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
      };

      ctx.validate(model, body);

      const result = await service[_service].findRecordStatistics(body);
      console.log('find record many', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async exportRecordExcel() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
      };

      ctx.validate(model, body);

      const result = await service[_service].exportRecordExcel(body);
      console.log('find exportExcel many', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async findPaymentMany() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
        path: { type: 'string' },
      };
      console.log('find payment many', body);
      ctx.validate(model, body);

      const result = await service[_service].findPaymentMany(body);
      console.log('find payment many', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async procureRecordAssess() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
      };
      console.log('find payment many', body);
      ctx.validate(model, body);

      const result = await service[_service].procureRecordAssess(body);
      console.log('find payment many', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }
  async fixedAssess() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
      };
      console.log('find payment many', body);
      ctx.validate(model, body);

      const result = await service[_service].fixedAssess(body);
      console.log('find payment many', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async findShippingFeeMany() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        tenantCode: { type: 'string' },
      };

      ctx.validate(model, body);

      const result = await service[_service].findShippingFeeMany(body);
      console.log('find exportExcel many', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }


  async assess() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        createdTs: { type: 'array' },
      };
      console.log('finance access', body);
      ctx.validate(model, body);

      const result = await service[_service].assess(body);
      console.log('find payment many', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }
  async taxAssess() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        createdTs: { type: 'array' },
      };

      ctx.validate(model, body);

      const result = await service[_service].taxAssess(body);
      console.log('find payment many', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }
  /**
   * 创建开票、收票记录
   * @returns {Promise<void>}
   */
  async createInvoiceRecord() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        code: { type: 'string' },
        type: { type: 'string' },
      };
      console.log('createInvoiceRecord', body);
      ctx.validate(model, body);
      body.recordId = 'INV' + moment()
        .format('YYYYMMDDHHmmss');
      const result = await ctx.app.dbs.insert('Invoice', body);
      ctx.body = {status:'ok',result};
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async updateInvoiceRecord() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        recordId: { type: 'string' },
      };
      console.log('updateInvoiceRecord', body);
      ctx.validate(model, body);
      const result = await service[_service].updateInvoiceRecord(body);
      console.log('find updateInvoiceRecord many', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }
  async deleteInvoiceRecord() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        recordId: { type: 'string' },
      };
      console.log('deleteInvoiceRecord', body);
      ctx.validate(model, body);
      const result = await service[_service].deleteInvoiceRecord(body);
      console.log('find deleteInvoiceRecord many', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  async findInvoiceRecords() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        createdTs: { type: 'array' },
      };
      console.log('finance access', body);
      ctx.validate(model, body);

      const result = await service[_service].findInvoiceRecordMany(body);
      console.log('find findInvoiceRecords many', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }
  async findInvoiceSalesMany() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        createdTs: { type: 'array' },
      };

      ctx.validate(model, body);
      const result = await service[_service].findInvoiceSalesMany(body);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  /**
   * 开票统计
   * @returns {Promise<void>}
   */
  async invoiceAssess() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        createdTs: { type: 'array' },
      };
      console.log('finance invoiceAssess', body);
      ctx.validate(model, body);

      const result = await service[_service].invoiceAssess(body);
      console.log('find invoiceAssess', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }
  async findInvoiceProcureMany() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        createdTs: { type: 'array' },
      };

      ctx.validate(model, body);
      const result = await service[_service].findInvoiceProcureMany(body);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }

  /**
   * 开票统计
   * @returns {Promise<void>}
   */
  async invoiceReceiptAssess() {
    const { ctx, service } = this;
    try {
      const { body } = ctx.request;
      const model = {
        createdTs: { type: 'array' },
      };
      console.log('finance invoiceAssess', body);
      ctx.validate(model, body);

      const result = await service[_service].invoiceReceiptAssess(body);
      console.log('find invoiceAssess', result);
      ctx.body = result;
      ctx.status = 200;
    } catch (e) {
      console.error(e);
      const _message = e && e.message ? e.message : this.ERROR_MSG;
      ctx.body = { status: 'error', message: _message, result: e };
      ctx.status = 200;
    }
  }
}

module.exports = FinanceController;


